﻿#include "KLineView.h"

#include <QPainter>
#include <QPaintEvent>
#include <QDebug>
#include <QVector>
#include <QRect>

#include "KLineCanvasContext.h"
#include "KLineMouseContext.h"
#include "KLineViewContext.h"
#include "KLayer.h"
#include "KColorStyle.h"
#include "KIndicatorLayer.h"
#include "KLineLayer.h"

class KLineView::KLineViewPrivate :public QObject
{
public:
	KLineViewContext context;

	QRectF left_tracking_rect;
	QRectF right_tracking_rect;
	bool selected;
	int layer_count;

	QVector<KLineLayer*> layers;

	KLineLayer* main_layer;
public:
	KLineViewPrivate(QObject*parent):QObject(parent)
	{
		selected = false;

		//KIndicatorLayer*l = new KIndicatorLayer(this);
		//l->setViewContext(&context);
		//layers.append(l);

		//KLineLayer*ll = new KLineLayer(this);
		//ll->setViewContext(&context);
		//layers.append(ll);

		layer_count = 0;
		main_layer = nullptr;
	}
	int dataLength()
	{
		int r = 0, t;
		for (auto a : layers) {
			t = a->dataLength();
			if (t > r)
				t = r;
		}
		return r;
	}
	void getMaxMinValue(int start_idx, int count, QVariant*max_v, QVariant*min_v)
	{
		bool ok = false;
		double ax, in, ax_t, in_t;
		for (auto a : layers) {
			if (a->getMaxMinValue(start_idx, count, &ax_t, &in_t)) {
				if (!ok) {
					ok = true;
					ax = ax_t;
					in = in_t;
				}
				else {
					if (ax < ax_t) ax = ax_t;
					if (in > in_t) in = in_t;
				}
			}
		}
		if (ok) {
			context.max_value = ax;
			context.min_value = in;
		}
		else {
			context.max_value = 0;
			context.min_value = 0;
		}
	}
	int getMaxItemCount()
	{
		int r = 0, n;
		for (auto a : layers) {
			n = a->dataLength();
			if (n > r)
				r = n;
		}
		return r;
	}

};

KLineView::KLineView(QObject *parent)
	: KView(parent),private_ptr(new KLineViewPrivate(this))
{
}

KLineView::~KLineView()
{}

void KLineView::setTrackingArea(const QRectF&l, const QRectF&r)
{
	private_ptr->left_tracking_rect = l;
	private_ptr->right_tracking_rect = r;
}
void KLineView::setCanvasContext(KLineCanvasContext*_)
{
	private_ptr->context.canvas_context = _;
}
KLineViewContext* KLineView::context()
{
	return &private_ptr->context;
}
bool KLineView::selected()
{
	return private_ptr->selected;
}
void KLineView::setSelected(bool b)
{
	private_ptr->selected = b;
}
int KLineView::dataLength()
{
	return private_ptr->dataLength();
}
void KLineView::getMaxMinValue(int start_idx, int count, QVariant*max_v, QVariant*min_v)
{
	private_ptr->getMaxMinValue(start_idx, count, max_v, min_v);
}
int KLineView::getMaxItemCount()
{
	return private_ptr->getMaxItemCount();
}

KLineLayer* KLineView::mainLayer()
{
	return private_ptr->main_layer;
}
void KLineView::setMainLayer(KLineLayer*_)
{
	if (private_ptr->main_layer == _)
		return;
	
	if (private_ptr->main_layer) {
		private_ptr->layers.removeAll(private_ptr->main_layer);
		delete private_ptr->main_layer;
	}
	_->setViewContext(&private_ptr->context);
	_->setRect(this->rect());
	private_ptr->main_layer = _;

	private_ptr->layers.append(_);
	private_ptr->getMaxMinValue(private_ptr->context.canvas_context->item_startidx, private_ptr->context.canvas_context->canvas_colcount, nullptr, nullptr);
}
void KLineView::addLayer(KLineLayer*_)
{
	KLineLayer*l = layer(_->name());
	if (l)
		return;

	private_ptr->layer_count++;

	_->setViewContext(&private_ptr->context);
	_->setRect(this->rect());

	private_ptr->layers.append(_);
	private_ptr->getMaxMinValue(private_ptr->context.canvas_context->item_startidx, private_ptr->context.canvas_context->canvas_colcount, nullptr, nullptr);
}
KLineLayer* KLineView::layer(const QString&s)
{
	for (auto a : private_ptr->layers) {
		if (s.compare(a->name(), Qt::CaseInsensitive) == 0)
			return a;
	}
	return nullptr;
}
void KLineView::removeLayer(const QString&s)
{
	private_ptr->layers.removeAll(layer(s));
	private_ptr->getMaxMinValue(private_ptr->context.canvas_context->item_startidx, private_ptr->context.canvas_context->canvas_colcount, nullptr, nullptr);
}
int KLineView::layerCount()
{
	return private_ptr->layers.count();
}
void KLineView::drawViewSelected(QPainter*painter, QPaintEvent *event)
{
	painter->save();

	// 小三角区域;
	QPolygonF trianglePolygon;
	trianglePolygon << rect().topRight();
	trianglePolygon << QPointF(rect().right() - 13, rect().top());
	trianglePolygon << QPointF(rect().right(), rect().top() + 13);

	QPainterPath path;
	path.addPolygon(trianglePolygon);

	painter->fillPath(path, private_ptr->context.canvas_context->color_style->color(KColorStyle::KCOLOR_BORDER));//QBrush(qRgb(255, 0, 0)));

	painter->restore();
}
//QRectF KLineView::rect()
//{}
void KLineView::setRect(const QRectF&_)
{
	KView::setRect(_);
	private_ptr->context.rt_view = _.adjusted(0, 1, 0, -1);
}

void KLineView::onCanvasDraging()
{
	// 计算最大最小值
}
bool KLineView::updateMouseContext(const QPointF&pt, KLineMouseContext*ctx)
{
	for (auto a : private_ptr->layers) {
		if (a->contain(pt)) {
			ctx->area_id = VIEWAREA_INDICATOR_DATA;
			// ctx->data
			return true;
		}
	}
	ctx->area_id = VIEWAREA_NONE;
	return true;
}
void KLineView::onPaint(QPainter*p, QPaintEvent *event)
{
	p->save();
	p->setClipRect(rect());
	if (selected()) {
		drawViewSelected(p, event);
	}

	for (auto a : private_ptr->layers)
		a->draw(p);
	//QRectF rc = p->clipBoundingRect().intersected(rect());
	//p->fillRect(rc, Qt::yellow);
	p->restore();
}
